{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xvxe3WD8zpPf"
      },
      "source": [
        "# 使用 Transformers 进行 Yi 模型推理\n",
        "\n",
        "欢迎来到这个使用 Hugging Face Transformers 库进行 Yi 模型推理的教程！在这个 Notebook 中,我们将一步步指导你如何使用 Transformers 来加载和运行 Yi-1.5-6B-Chat 模型。这个过程很简单,即使你是新手也能轻松掌握。\n",
        "\n",
        "## 为什么选择 Transformers?\n",
        "\n",
        "Hugging Face 的 Transformers 库是一个非常流行的开源 Python 库,它提供了:\n",
        "- 大量预训练的模型\n",
        "- 简单易用的 API\n",
        "- 强大的社区支持\n",
        "\n",
        "使用 Transformers,你可以轻松地下载、加载和使用各种基于 Transformer 架构的模型,包括我们今天要使用的 Yi 模型。\n",
        "\n",
        "让我们开始吧!"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wM4hfxVBzpPi"
      },
      "source": [
        "## 步骤 1: 安装必要的库\n",
        "\n",
        "首先,我们需要安装 Transformers 库和其他必要的依赖。运行下面的单元格来完成安装:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "collapsed": true,
        "id": "fbd2dTQTzpPi",
        "outputId": "f757f820-27f7-4bdc-c095-e062d2b31aaf"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "/bin/bash: line 1: =2.3.0: No such file or directory\n",
            "Requirement already satisfied: accelerate in /usr/local/lib/python3.10/dist-packages (0.32.1)\n",
            "Requirement already satisfied: numpy<2.0.0,>=1.17 in /usr/local/lib/python3.10/dist-packages (from accelerate) (1.25.2)\n",
            "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from accelerate) (24.1)\n",
            "Requirement already satisfied: psutil in /usr/local/lib/python3.10/dist-packages (from accelerate) (5.9.5)\n",
            "Requirement already satisfied: pyyaml in /usr/local/lib/python3.10/dist-packages (from accelerate) (6.0.1)\n",
            "Requirement already satisfied: torch>=1.10.0 in /usr/local/lib/python3.10/dist-packages (from accelerate) (2.3.1+cu121)\n",
            "Requirement already satisfied: huggingface-hub in /usr/local/lib/python3.10/dist-packages (from accelerate) (0.23.5)\n",
            "Requirement already satisfied: safetensors>=0.3.1 in /usr/local/lib/python3.10/dist-packages (from accelerate) (0.4.3)\n",
            "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from torch>=1.10.0->accelerate) (3.15.4)\n",
            "Requirement already satisfied: typing-extensions>=4.8.0 in /usr/local/lib/python3.10/dist-packages (from torch>=1.10.0->accelerate) (4.12.2)\n",
            "Requirement already satisfied: sympy in /usr/local/lib/python3.10/dist-packages (from torch>=1.10.0->accelerate) (1.13.0)\n",
            "Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (from torch>=1.10.0->accelerate) (3.3)\n",
            "Requirement already satisfied: jinja2 in /usr/local/lib/python3.10/dist-packages (from torch>=1.10.0->accelerate) (3.1.4)\n",
            "Requirement already satisfied: fsspec in /usr/local/lib/python3.10/dist-packages (from torch>=1.10.0->accelerate) (2023.6.0)\n",
            "Collecting nvidia-cuda-nvrtc-cu12==12.1.105 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl (23.7 MB)\n",
            "Collecting nvidia-cuda-runtime-cu12==12.1.105 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl (823 kB)\n",
            "Collecting nvidia-cuda-cupti-cu12==12.1.105 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl (14.1 MB)\n",
            "Collecting nvidia-cudnn-cu12==8.9.2.26 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl (731.7 MB)\n",
            "Collecting nvidia-cublas-cu12==12.1.3.1 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl (410.6 MB)\n",
            "Collecting nvidia-cufft-cu12==11.0.2.54 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl (121.6 MB)\n",
            "Collecting nvidia-curand-cu12==10.3.2.106 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl (56.5 MB)\n",
            "Collecting nvidia-cusolver-cu12==11.4.5.107 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl (124.2 MB)\n",
            "Collecting nvidia-cusparse-cu12==12.1.0.106 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl (196.0 MB)\n",
            "Collecting nvidia-nccl-cu12==2.20.5 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_x86_64.whl (176.2 MB)\n",
            "Collecting nvidia-nvtx-cu12==12.1.105 (from torch>=1.10.0->accelerate)\n",
            "  Using cached nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl (99 kB)\n",
            "Requirement already satisfied: triton==2.3.1 in /usr/local/lib/python3.10/dist-packages (from torch>=1.10.0->accelerate) (2.3.1)\n",
            "Collecting nvidia-nvjitlink-cu12 (from nvidia-cusolver-cu12==11.4.5.107->torch>=1.10.0->accelerate)\n",
            "  Downloading nvidia_nvjitlink_cu12-12.5.82-py3-none-manylinux2014_x86_64.whl (21.3 MB)\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m21.3/21.3 MB\u001b[0m \u001b[31m58.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hRequirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from huggingface-hub->accelerate) (2.31.0)\n",
            "Requirement already satisfied: tqdm>=4.42.1 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub->accelerate) (4.66.4)\n",
            "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->torch>=1.10.0->accelerate) (2.1.5)\n",
            "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub->accelerate) (3.3.2)\n",
            "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub->accelerate) (3.7)\n",
            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub->accelerate) (2.0.7)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub->accelerate) (2024.7.4)\n",
            "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from sympy->torch>=1.10.0->accelerate) (1.3.0)\n",
            "Installing collected packages: nvidia-nvtx-cu12, nvidia-nvjitlink-cu12, nvidia-nccl-cu12, nvidia-curand-cu12, nvidia-cufft-cu12, nvidia-cuda-runtime-cu12, nvidia-cuda-nvrtc-cu12, nvidia-cuda-cupti-cu12, nvidia-cublas-cu12, nvidia-cusparse-cu12, nvidia-cudnn-cu12, nvidia-cusolver-cu12\n",
            "Successfully installed nvidia-cublas-cu12-12.1.3.1 nvidia-cuda-cupti-cu12-12.1.105 nvidia-cuda-nvrtc-cu12-12.1.105 nvidia-cuda-runtime-cu12-12.1.105 nvidia-cudnn-cu12-8.9.2.26 nvidia-cufft-cu12-11.0.2.54 nvidia-curand-cu12-10.3.2.106 nvidia-cusolver-cu12-11.4.5.107 nvidia-cusparse-cu12-12.1.0.106 nvidia-nccl-cu12-2.20.5 nvidia-nvjitlink-cu12-12.5.82 nvidia-nvtx-cu12-12.1.105\n",
            "Requirement already satisfied: sentencepiece in /usr/local/lib/python3.10/dist-packages (0.1.99)\n"
          ]
        }
      ],
      "source": [
        "!pip install transformers>=4.36.2\n",
        "!pip install gradio>=4.13.0\n",
        "!pip install torch>=2.0.1,<=2.3.0\n",
        "!pip install accelerate\n",
        "!pip install sentencepiece"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-JR5VQT8zpPj"
      },
      "source": [
        "这些库的作用如下:\n",
        "- `transformers`: 用于加载和使用 Yi 模型\n",
        "- `gradio`: 用于创建简单的 Web 界面(如果需要的话，教程其实没有，如果需要可以参考其它的notebook)\n",
        "- `torch`: PyTorch 库\n",
        "- `accelerate`: 用于加速模型加载和推理\n",
        "- `sentencepiece`: 用于模型的分词处理\n",
        "\n",
        "安装完成后,我们就可以开始使用模型了!"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-HBub2O9zpPj"
      },
      "source": [
        "## 步骤 2: 导入必要的库并加载模型\n",
        "\n",
        "现在,让我们导入需要的库并加载 Yi-1.5-6B-Chat 模型。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 85,
          "referenced_widgets": [
            "9c17c899567b4a43804ae3e94f7a1619",
            "a64d67f5d8fc404fbc794f5ef763d5f0",
            "94ba60acb4b342b4aba96550a66a1408",
            "d8f3e7d56379476bacad599edd60af5a",
            "1d0151a369b8446a8f196dfa150faa09",
            "b6fa949bac5b4a0ab68472876a490cbd",
            "6490b983cb9346fb856c0b65b6f70f10",
            "911e75c07d1d49f993e7e76ba3df3ad8",
            "abc8333bfec8411687e935c2e9fe29a0",
            "394303ab9de84dba90e448dbd3e906a9",
            "e756a6d37da0458090466e8f495dbc9d"
          ]
        },
        "id": "CH9VEKNzzpPk",
        "outputId": "12857c6d-5c45-46a7-cf01-cfc2c39eab19"
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "Loading checkpoint shards:   0%|          | 0/3 [00:00<?, ?it/s]"
            ],
            "application/vnd.jupyter.widget-view+json": {
              "version_major": 2,
              "version_minor": 0,
              "model_id": "9c17c899567b4a43804ae3e94f7a1619"
            }
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "WARNING:accelerate.big_modeling:Some parameters are on the meta device device because they were offloaded to the cpu.\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Model loading complete!\n"
          ]
        }
      ],
      "source": [
        "from transformers import AutoModelForCausalLM, AutoTokenizer\n",
        "\n",
        "# 设置模型路径\n",
        "model_path = '01-ai/Yi-1.5-6B-Chat'\n",
        "\n",
        "# 加载分词器\n",
        "tokenizer = AutoTokenizer.from_pretrained(model_path, use_fast=False)\n",
        "\n",
        "# 加载模型\n",
        "model = AutoModelForCausalLM.from_pretrained(\n",
        "    model_path,\n",
        "    device_map=\"auto\",  # 自动选择可用的设备\n",
        "    torch_dtype='auto'  # 自动选择合适的数据类型\n",
        ").eval()  # 将模型设置为评估模式\n",
        "\n",
        "print(\"Model loading complete!\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dVD5V3sezpPk"
      },
      "source": [
        "在这段代码中:\n",
        "- `AutoTokenizer` 用于加载与模型匹配的分词器。\n",
        "- `AutoModelForCausalLM` 用于加载语言模型。\n",
        "- `device_map=\"auto\"` 让模型自动选择最佳的设备(CPU 或 GPU)。\n",
        "- `torch_dtype='auto'` 自动选择合适的数据类型,以优化性能。\n",
        "- `.eval()` 将模型设置为评估模式,这在进行推理时很重要。\n",
        "\n",
        "⚠️ 注意: 加载模型可能需要一些时间,具体取决于你的网络速度和电脑性能。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AP5I1VjzzpPk"
      },
      "source": [
        "## 步骤 3: 准备输入并进行推理\n",
        "\n",
        "现在我们的模型已经加载完毕,让我们来尝试进行一次简单的对话!"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "wxfGtqDPzpPl",
        "outputId": "be7d481e-ee49-4ed2-9ed9-d6c36dbb8d35"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.10/dist-packages/transformers/generation/utils.py:1249: UserWarning: Using the model-agnostic default `max_length` (=20) to control the generation length. We recommend setting `max_new_tokens` to control the maximum length of the generation.\n",
            "  warnings.warn(\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Yi: Hello! How can I assist you today?\n"
          ]
        }
      ],
      "source": [
        "# 准备对话内容\n",
        "messages = [\n",
        "    {\"role\": \"user\", \"content\": \"Hi!\"}\n",
        "]\n",
        "\n",
        "# 将对话转换为模型可以理解的格式\n",
        "input_ids = tokenizer.apply_chat_template(conversation=messages, tokenize=True, add_generation_prompt=True, return_tensors='pt')\n",
        "\n",
        "# 使用模型生成回复\n",
        "output_ids = model.generate(input_ids.to('cuda'))\n",
        "\n",
        "# 解码模型的输出\n",
        "response = tokenizer.decode(output_ids[0][input_ids.shape[1]:], skip_special_tokens=True)\n",
        "\n",
        "print(f\"Yi: {response}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4bDM7eA8zpPl"
      },
      "source": [
        "让我们来解释一下这段代码:\n",
        "\n",
        "1. 我们首先创建了一个包含用户消息的列表。\n",
        "2. `apply_chat_template` 方法将我们的消息转换为模型可以理解的格式。\n",
        "3. `model.generate` 使用转换后的输入生成回复。\n",
        "4. 最后,我们使用 `tokenizer.decode` 将模型的输出转换回可读的文本。\n",
        "\n",
        "你可以通过修改 `messages` 列表来尝试不同的对话!"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bCJ1TWHmzpPl"
      },
      "source": [
        "## 进阶: 创建一个简单的对话函数\n",
        "\n",
        "为了更方便地与模型进行多轮对话,我们可以创建一个简单的函数:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "BysLObcOzpPl",
        "outputId": "3a6bec71-8d80-47ad-d794-2c9127746b1a"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "user: Hi!\n",
            "Yi: Hello! How can I assist you today?\n",
            "\n",
            "user: Can you tell me a joke?\n",
            "Yi: Sure, here's one for you:\n",
            "\n",
            "Why don't skeletons fight each other?\n",
            "\n",
            "They don't have the guts.\n",
            "\n"
          ]
        }
      ],
      "source": [
        "def chat_with_yi(user_input, history=[]):\n",
        "    # 将新的用户输入添加到历史对话中\n",
        "    history.append({\"role\": \"user\", \"content\": user_input})\n",
        "\n",
        "    # 准备输入\n",
        "    input_ids = tokenizer.apply_chat_template(conversation=history, tokenize=True, add_generation_prompt=True, return_tensors='pt')\n",
        "\n",
        "    # 生成回复\n",
        "    output_ids = model.generate(input_ids.to('cuda'), max_new_tokens=100)\n",
        "\n",
        "    # 解码回复\n",
        "    response = tokenizer.decode(output_ids[0][input_ids.shape[1]:], skip_special_tokens=True)\n",
        "\n",
        "    # 将模型的回复添加到历史对话中\n",
        "    history.append({\"role\": \"assistant\", \"content\": response})\n",
        "\n",
        "    return response, history\n",
        "\n",
        "# 测试对话函数\n",
        "history = []\n",
        "user_inputs = [\"Hi!\", \"Can you tell me a joke?\"]\n",
        "\n",
        "for user_input in user_inputs:\n",
        "    print(f\"user: {user_input}\")\n",
        "    response, history = chat_with_yi(user_input, history)\n",
        "    print(f\"Yi: {response}\\n\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Avq0B_4FzpPm"
      },
      "source": [
        "这个函数允许你轻松地进行多轮对话,并保持对话的上下文。你可以根据需要继续添加更多的用户输入来测试模型的表现。\n",
        "\n",
        "## 结语\n",
        "\n",
        "恭喜你!你已经成功使用 Transformers 库加载并运行了 Yi-1.5-6B-Chat 模型。\n",
        "\n",
        "本次教程到这里就结束啦!如果你有任何问题,随时查阅 Transformers 的[官方文档](https://huggingface.co/docs/transformers/index)或寻求Yi社区的帮助。"
      ]
    }
  ],
  "metadata": {
    "language_info": {
      "name": "python"
    },
    "colab": {
      "provenance": [],
      "machine_shape": "hm",
      "gpuType": "L4"
    },
    "accelerator": "GPU",
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "9c17c899567b4a43804ae3e94f7a1619": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_a64d67f5d8fc404fbc794f5ef763d5f0",
              "IPY_MODEL_94ba60acb4b342b4aba96550a66a1408",
              "IPY_MODEL_d8f3e7d56379476bacad599edd60af5a"
            ],
            "layout": "IPY_MODEL_1d0151a369b8446a8f196dfa150faa09"
          }
        },
        "a64d67f5d8fc404fbc794f5ef763d5f0": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_b6fa949bac5b4a0ab68472876a490cbd",
            "placeholder": "​",
            "style": "IPY_MODEL_6490b983cb9346fb856c0b65b6f70f10",
            "value": "Loading checkpoint shards: 100%"
          }
        },
        "94ba60acb4b342b4aba96550a66a1408": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_911e75c07d1d49f993e7e76ba3df3ad8",
            "max": 3,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_abc8333bfec8411687e935c2e9fe29a0",
            "value": 3
          }
        },
        "d8f3e7d56379476bacad599edd60af5a": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_394303ab9de84dba90e448dbd3e906a9",
            "placeholder": "​",
            "style": "IPY_MODEL_e756a6d37da0458090466e8f495dbc9d",
            "value": " 3/3 [00:03&lt;00:00,  1.11it/s]"
          }
        },
        "1d0151a369b8446a8f196dfa150faa09": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "b6fa949bac5b4a0ab68472876a490cbd": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "6490b983cb9346fb856c0b65b6f70f10": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "911e75c07d1d49f993e7e76ba3df3ad8": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "abc8333bfec8411687e935c2e9fe29a0": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "394303ab9de84dba90e448dbd3e906a9": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "e756a6d37da0458090466e8f495dbc9d": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        }
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}